#ifndef skyTreeNode_h__
#define skyTreeNode_h__

#include "./skyObject.h"

namespace Sky
{
	class TreeNode : public Object
	{
		DECL_RTTI1(TreeNode,Object);
	public:
		TreeNode* m_Prev;
		TreeNode* m_Next;
		TreeNode* m_Parent;
		TreeNode* m_FirstChild;
		TreeNode* m_LastChild;
		TUint	  m_Id;
	public:
		TreeNode();
		TreeNode(TUint id);
		//
		TreeNode* getParent();
		//
		TreeNode* getFirstChild();
		//
		TreeNode* getLastChild();
		//
		TreeNode* getNextSibling();
		//
		TreeNode* getPrevSibling();
		//
		TreeNode* getNext();
		//
		TreeNode* getNext_InSubTree(TreeNode* node);
		//
		TreeNode* getPrev_InSubTree(TreeNode* node);
		//
		TreeNode* getPrev();
		//
		TreeNode* getNext_OverChild();
	public:
		TBool attachFirstChild(TreeNode* child);
		TBool attachLastChild(TreeNode* child);
		TBool attachNextSibling(TreeNode* sibling);
		TBool attachPrveSibling(TreeNode* sibling);

		TreeNode* detachFirstChild();
		TreeNode* detachLastChild();
		TreeNode* detachNextSibling();
		TreeNode* detachPrevSibling();
		TreeNode* detachCurrent();
		//deatch itself as an clone one
		TreeNode* detachColne();
		TreeNode* exchangeCurrent(TreeNode* node);
		TreeNode* detachAllChildren();
	};

	class TreeManager
	{
	public:
		TreeNode* m_Root;
		TreeManager():m_Root(vNull){};
		template <typename DerivedType>
		static TreeNode* cast(DerivedType cls);
	public:
		TBool	   attachLastChildOf(TreeNode* node,TreeNode* child);
		TBool	   attachFirstChildOf(TreeNode* node,TreeNode* child);
		TBool	   attachNextSiblingOf(TreeNode* node,TreeNode* sibling);
		TBool	   attachPrevSiblingOf(TreeNode* node,TreeNode* sibling);

		TreeNode*	   detach(TreeNode* node);
		TreeNode*	   detachAllChildrenOf(TreeNode* node);
		TreeNode*	   detachLastChildOf(TreeNode* node);
		TreeNode*	   detachFirstChildOf(TreeNode* node);
		TreeNode*	   detachPrevSiblingOf(TreeNode* node);
		TreeNode*	   detachNextSiblingOf(TreeNode* node);
		TreeNode*	   exchange(TreeNode* thisNode,TreeNode* thatNode);
	public:
		TreeNode*	   getParentOf(TreeNode* node);
		TreeNode*	   getLastChildOf(TreeNode* node);
		TreeNode*	   getFirstChildOf(TreeNode* node);
		TreeNode*	   getPrevSiblingOf(TreeNode* node);
		TreeNode*	   getNextSiblingOf(TreeNode* node);

		TreeNode*	   getParentFirsTraverseOf(TreeNode* node);
		TreeNode*	   getParentFirsTraverseOf_Reverse(TreeNode* node);
		TreeNode*	   getSubTreeParentFirsTraverseOf(TreeNode* node,TreeNode* subRoot);

		TreeNode*	   getParentLastTraverseOf(TreeNode* node);

		TBool		   setRoot(TreeNode* root);
		TreeNode*	   getRoot(){return m_Root;};
		TreeNode*	   getTreeNode(TUint id);
		TBool		   isBelongTree(TreeNode* node);
	};

	template <typename DerivedType>
	TreeNode* TreeManager::cast( DerivedType cls )
	{
		return (TreeNode*)cls;
	}
}
#endif // skyTreeNode_h__